/*
 * LVGL display and input driver implementation for ESP32-S3
 */
#include "lvgl_driver.h"
#include "lvgl_init.h"
#include "../include/lcd/lcd_init.h"
#include "../include/lcd/lcd.h"
#include "../include/lcd/cst816.h"
#include "Arduino.h"

// 创建显示驱动和输入设备驱动对象
static lv_disp_drv_t disp_drv;
static lv_indev_drv_t indev_drv;

// 触摸坐标缓存
static int32_t touch_x = 0;
static int32_t touch_y = 0;
static bool touch_pressed = false;

/**
 * @brief 显示刷新回调函数，由LVGL调用以更新显示内容
 */
static void disp_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
  // 不需要设置区域，使用LCD_DrawPoint逐点绘制
  // 遍历区域内的每个像素点
  printf("Flush area: x1=%d, y1=%d, x2=%d, y2=%d\n", area->x1, area->y1, area->x2, area->y2);
  LCD_Color_Fill(area->x1, area->y1, area->x2, area->y2, (uint16_t*)color_p);
  
  // 通知LVGL刷新完成
  lv_disp_flush_ready(disp_drv);
}

/**
 * @brief 触摸板读取回调函数，由LVGL调用以获取触摸状态
 */
static void touchpad_read_cb(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
  // 读取触摸状态
  if (CST816_Get_FingerNum() > 0) {
    // 有触摸，获取坐标
    CST816_Get_XY_AXIS();
    touch_x = CST816_Instance.X_Pos;
    touch_y = CST816_Instance.Y_Pos;
    touch_pressed = true;
  } else {
    touch_pressed = false;
  }
  
  // 设置LVGL输入数据
  data->point.x = touch_x;
  data->point.y = touch_y;
  data->state = touch_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
}

/**
 * @brief 初始化LVGL显示驱动
 */
void lvgl_display_driver_init(void)
{
  // 初始化LCD
  LCD_Init();
  LCD_Fill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, YELLOW);
  // 初始化显示驱动配置
  lv_disp_drv_init(&disp_drv);
  
  // 设置显示参数
  disp_drv.hor_res = 240;
  disp_drv.ver_res = 280;
  
  // 设置显示缓冲区
  disp_drv.draw_buf = lvgl_init_draw_buf_get();
  
  // 设置刷新回调
  disp_drv.flush_cb = disp_flush_cb;
  
  // 注册显示驱动
  lv_disp_drv_register(&disp_drv);
  
  Serial.println("LVGL display driver initialized");
}

/**
 * @brief 初始化LVGL触摸驱动
 */
void lvgl_touch_driver_init(void)
{
  // 初始化触摸屏幕
  CST816_Init();
  
  // 配置触摸参数，启用所有手势
  CST816_Config_MotionMask(M_ALLENABLE);
  
  // 初始化输入设备驱动配置
  lv_indev_drv_init(&indev_drv);
  
  // 设置输入设备类型
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  
  // 设置读取回调
  indev_drv.read_cb = touchpad_read_cb;
  
  // 注册输入设备驱动
  lv_indev_drv_register(&indev_drv);
  
  Serial.println("LVGL touch driver initialized");
}